/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


/*************************************************************************
 *\author: starlove
 *************************************************************************/
#ifndef __CC_PYTHON_IMPORT_O_EXT_SCROLLVIEW__
#define __CC_PYTHON_IMPORT_O_EXT_SCROLLVIEW__

#include <cocos2d.h>
#include <cocos-ext.h>
#include "python_object_nodeobjects.h"

NS_CCPY_BEGIN
	CC_OBJECT_WRAPPER_DEF_BEGIN(CCScrollView)
	CCLAYER_OBJECT_WRAPPER_DEF(CCScrollView)
	CC_OBJECT_WRAPPER_DEF_END

	class CPyScrollView : public CPyCCObject
	{
	PYCLASS_DEF_INTERFACE(CPyScrollView)
	public:
		CPyScrollView();
		PYCLASS_METHOD_KW_DEF(CPyScrollView, setContentOffset);
		PYCLASS_METHOD_DEF(CPyScrollView, getContentOffset);
		PYCLASS_METHOD_DEF(CPyScrollView, setContentOffsetInDuration);
		PYCLASS_METHOD_KW_DEF(CPyScrollView, setZoomScale);
		PYCLASS_METHOD_DEF(CPyScrollView, getZoomScale);
		PYCLASS_METHOD_DEF(CPyScrollView, setZoomScaleInDuration);
		PYCLASS_METHOD_DEF(CPyScrollView, updateInset);
		PYCLASS_METHOD_DEF(CPyScrollView, isNodeVisible);
		PYCLASS_METHOD_DEF(CPyScrollView, pause);
		PYCLASS_METHOD_DEF(CPyScrollView, resume);
		PYCLASS_GET_DEF(CPyScrollView, minContainerOffset);
		PYCLASS_GET_DEF(CPyScrollView, maxContainerOffset);	
		PYCLASS_GET_DEF(CPyScrollView, Dragging);
		PYCLASS_GET_DEF(CPyScrollView, TouchMoved);
		PYCLASS_GETSET_MAPPING_DEF(CPyScrollView, Bounceable);
		PYCLASS_GETSET_MAPPING_DEF(CPyScrollView, ViewSize);
		PYCLASS_GETSET_MAPPING_DEF(CPyScrollView, Container);
		PYCLASS_GETSET_MAPPING_DEF(CPyScrollView, Direction);
		PYCLASS_GETSET_MAPPING_DEF(CPyScrollView, Delegate);
		PYCLASS_GETSET_MAPPING_DEF(CPyScrollView, ClippingToBounds);
	};

	class CWrapScrollViewDelegate : public CCScrollViewDelegate
	{
	public:
		CWrapScrollViewDelegate(PyObject *fn)
		{
			m_fn = fn;
			//Py_XINCREF(fn);
		}

		~CWrapScrollViewDelegate()
		{
			//Py_SAFE_DECREF(m_fn);
		}

		void scrollViewDidScroll(CCScrollView* view)
		{
			if(m_fn)
			{
				CPyScrollView *pview = CPyCCObject::create<CPyScrollView>(view);
				PyObject_CallMethod(m_fn, "scrollViewDidScroll", "O", (PyObject *)pview);
			}
		}

		void scrollViewDidZoom(CCScrollView* view)
		{
			if(m_fn)
			{
				CPyScrollView *pview = CPyCCObject::create<CPyScrollView>(view);
				PyObject_CallMethod(m_fn, "scrollViewDidZoom", "O", (PyObject *)pview);
			}
		}

		PyObject *getPyObject()
		{
			return m_fn;
		}

	private:
		PyObject *m_fn;
	};

	class CPyScrollViewDelegate : public CPyClassBase
	{
	PYCLASS_DEF_INTERFACE(CPyScrollViewDelegate)
	public:
		CPyScrollViewDelegate()
		{
			m_cobject = new CWrapScrollViewDelegate((PyObject *)this);
		}
		CCScrollViewDelegate *getCObject()
		{
			return dynamic_cast<CCScrollViewDelegate *>(m_cobject);
		}
		PYCLASS_METHOD_DEF(CPyScrollViewDelegate, scrollViewDidScroll);
		PYCLASS_METHOD_DEF(CPyScrollViewDelegate, scrollViewDidZoom);
	private:
		CWrapScrollViewDelegate *m_cobject;
	};
	

	CCNODE_OBJECT_WRAPPER_DEF(CCTableViewCell)

	class CPyTableViewCell : public CPyCCObject
	{
	PYCLASS_DEF_INTERFACE(CPyTableViewCell)
	public:
		CPyTableViewCell();
		PYCLASS_METHOD_DEF(CPyTableViewCell, reset);
		PYCLASS_GETSET_MAPPING_DEF(CPyTableViewCell, ObjectID);
		PYCLASS_GETSET_MAPPING_DEF(CPyTableViewCell, Idx);
	};

	CC_OBJECT_WRAPPER_DEF_BEGIN(CCTableView)
	CCLAYER_OBJECT_WRAPPER_DEF(CCTableView)
	CC_OBJECT_WRAPPER_DEF_END

	class CPyTableView : public CPyCCObject
	{
	PYCLASS_DEF_INTERFACE(CPyTableView)
	public:
		CPyTableView();
		PYCLASS_GETSET_MAPPING_DEF(CPyTableView, DataSource);
		PYCLASS_GETSET_MAPPING_DEF(CPyTableView, Delegate);
		PYCLASS_GETSET_MAPPING_DEF(CPyTableView, VerticalFillOrder);
		PYCLASS_METHOD_DEF(CPyTableView, initWithViewSize);
		PYCLASS_METHOD_DEF(CPyTableView, updateCellAtIndex);
		PYCLASS_METHOD_DEF(CPyTableView, insertCellAtIndex);
		PYCLASS_METHOD_DEF(CPyTableView, removeCellAtIndex);
		PYCLASS_METHOD_DEF(CPyTableView, reloadData);
		PYCLASS_METHOD_DEF(CPyTableView, dequeueCell);
		PYCLASS_METHOD_DEF(CPyTableView, cellAtIndex);
	};
	
	class CWrapTableViewDelegate : public CCTableViewDelegate
	{
	public:
		CWrapTableViewDelegate(PyObject *fn)
		{
			m_fn = fn;
		}

		~CWrapTableViewDelegate()
		{
		}

		void tableCellTouched(CCTableView* table, CCTableViewCell* cell)
		{
			if(m_fn)
			{
				CPyTableView *pview = CPyCCObject::create<CPyTableView>(table);
				CPyTableViewCell *pcell = CPyCCObject::create<CPyTableViewCell>(cell);
				PyObject_CallMethod(m_fn, "tableCellTouched", "OO", (PyObject *)pview, (PyObject *)pcell);
			}
		}

		void tableCellHighlight(CCTableView* table, CCTableViewCell* cell)
		{
			if(m_fn)
			{
				CPyTableView *pview = CPyCCObject::create<CPyTableView>(table);
				CPyTableViewCell *pcell = CPyCCObject::create<CPyTableViewCell>(cell);
				PyObject_CallMethod(m_fn, "tableCellHighlight", "OO", (PyObject *)pview, (PyObject *)pcell);
			}
		}

		void tableCellUnhighlight(CCTableView* table, CCTableViewCell* cell)
		{
			if(m_fn)
			{
				CPyTableView *pview = CPyCCObject::create<CPyTableView>(table);
				CPyTableViewCell *pcell = CPyCCObject::create<CPyTableViewCell>(cell);
				PyObject_CallMethod(m_fn, "tableCellUnhighlight", "OO", (PyObject *)pview, (PyObject *)pcell);
			}
		}

		void tableCellWillRecycle(CCTableView* table, CCTableViewCell* cell)
		{
			if(m_fn)
			{
				CPyTableView *pview = CPyCCObject::create<CPyTableView>(table);
				CPyTableViewCell *pcell = CPyCCObject::create<CPyTableViewCell>(cell);
				PyObject_CallMethod(m_fn, "tableCellWillRecycle", "OO", (PyObject *)pview, (PyObject *)pcell);
			}
		}

		void scrollViewDidScroll(CCScrollView* view)
		{
			if(m_fn)
			{
				CPyScrollView *pview = CPyCCObject::create<CPyScrollView>(view);
				PyObject_CallMethod(m_fn, "scrollViewDidScroll", "O", (PyObject *)pview);
			}
		}

		void scrollViewDidZoom(CCScrollView* view)
		{
			if(m_fn)
			{
				CPyScrollView *pview = CPyCCObject::create<CPyScrollView>(view);
				PyObject_CallMethod(m_fn, "scrollViewDidZoom", "O", (PyObject *)pview);
			}
		}

		PyObject *getPyObject()
		{
			return m_fn;
		}

	private:
		PyObject *m_fn;
	};

	class CPyTableViewDelegate : public CPyScrollViewDelegate
	{
	PYCLASS_DEF_INTERFACE(CPyTableViewDelegate)
	public:
		CPyTableViewDelegate()
		{
			m_cobject = new CWrapTableViewDelegate((PyObject *)this);
		}
		CCTableViewDelegate *getCObject()
		{
			return dynamic_cast<CCTableViewDelegate *>(m_cobject);
		}
		PYCLASS_METHOD_DEF(CPyTableViewDelegate, tableCellTouched);
		PYCLASS_METHOD_DEF(CPyTableViewDelegate, tableCellHighlight);
		PYCLASS_METHOD_DEF(CPyTableViewDelegate, tableCellUnhighlight);
		PYCLASS_METHOD_DEF(CPyTableViewDelegate, tableCellWillRecycle);
	private:
		CWrapTableViewDelegate *m_cobject;
	};
	
	class CWrapTableViewDataSource : public CCTableViewDataSource
	{
	public:
		CWrapTableViewDataSource(PyObject *fn)
		{
			m_fn = fn;
		}

		~CWrapTableViewDataSource()
		{
		}

		CCSize tableCellSizeForIndex(CCTableView *table, unsigned int idx)
		{
			if(m_fn)
			{
				CPyTableView *pview = CPyCCObject::create<CPyTableView>(table);
				PyObject *ret = PyObject_CallMethod(m_fn, "tableCellSizeForIndex", "OI", (PyObject *)pview, PyLong_FromUnsignedLong(idx));
				if(ret && PyObject_TypeCheck(ret, CPyClassBase::GetTypeObject<CPySize>()))
					return ((CPySize *)ret)->getCCObject();
			}
			return cellSizeForTable(table);
		}

		CCSize cellSizeForTable(CCTableView *table)
		{
			if(m_fn)
			{
				CPyTableView *pview = CPyCCObject::create<CPyTableView>(table);
				PyObject *ret = PyObject_CallMethod(m_fn, "cellSizeForTable", "O", (PyObject *)pview);
				if(ret && PyObject_TypeCheck(ret, CPyClassBase::GetTypeObject<CPySize>()))
					return ((CPySize *)ret)->getCCObject();
			}
			return CCTableViewDataSource::cellSizeForTable(table);
		}

		CCTableViewCell* tableCellAtIndex(CCTableView *table, unsigned int idx)
		{
			if(m_fn)
			{
				CPyTableView *pview = CPyCCObject::create<CPyTableView>(table);
				PyObject *ret = PyObject_CallMethod(m_fn, "tableCellAtIndex", "OI", (PyObject *)pview, PyLong_FromUnsignedLong(idx));
				if(ret && PyObject_TypeCheck(ret, CPyClassBase::GetTypeObject<CPyTableViewCell>()))
					return (CCTableViewCell* )(((CPyTableViewCell *)ret)->getCCObject());
			}
			return NULL;
		}

		unsigned int numberOfCellsInTableView(CCTableView *table)
		{
			if(m_fn)
			{
				CPyTableView *pview = CPyCCObject::create<CPyTableView>(table);
				PyObject *ret = PyObject_CallMethod(m_fn, "numberOfCellsInTableView", "O", (PyObject *)pview);
				if(ret)
					return PyLong_AsUnsignedLong(ret);
			}
			return 0;
		}

		PyObject *getPyObject()
		{
			return m_fn;
		}

	private:
		PyObject *m_fn;
	};

	class CPyTableViewDataSource : public CPyClassBase
	{
	PYCLASS_DEF_INTERFACE(CPyTableViewDataSource)
	public:
		CPyTableViewDataSource()
		{
			m_cobject = new CWrapTableViewDataSource((PyObject *)this);
		}
		CCTableViewDataSource *getCObject()
		{
			return dynamic_cast<CCTableViewDataSource *>(m_cobject);
		}

		PYCLASS_METHOD_DEF(CPyTableViewDataSource, tableCellSizeForIndex);
		PYCLASS_METHOD_DEF(CPyTableViewDataSource, cellSizeForTable);
		PYCLASS_METHOD_DEF(CPyTableViewDataSource, tableCellAtIndex);
		PYCLASS_METHOD_DEF(CPyTableViewDataSource, numberOfCellsInTableView);
	private:
		CWrapTableViewDataSource *m_cobject;
	};
NS_CCPY_END

#endif